<template>
  <el-select
    v-model="selectedValue"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :size="size"
    :style="{ width: width }"
    @change="handleChange"
    @clear="handleClear"
  >
    <el-option
      v-for="dept in flatDeptOptions"
      :key="dept.id"
      :label="dept.label"
      :value="dept.id"
    />
  </el-select>
</template>

<script setup name="DeptSelect">
import { ref, computed, watch, onMounted } from 'vue'
import { deptTreeSelect } from '@/api/system/user'

// Props定义
const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: undefined
  },
  placeholder: {
    type: String,
    default: '请选择钓场'
  },
  clearable: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  size: {
    type: String,
    default: 'default'
  },
  width: {
    type: String,
    default: '100%'
  },
  onlyLeaf: {
    type: Boolean,
    default: true
  }
})

// Emits定义
const emit = defineEmits(['update:modelValue', 'change', 'clear'])

// 响应式数据
const deptTreeData = ref([])
const selectedValue = ref(props.modelValue)

// 计算属性：扁平化的部门选项
const flatDeptOptions = computed(() => {
  if (props.onlyLeaf) {
    return flattenTreeToLeafNodes(deptTreeData.value)
  } else {
    return flattenTreeToAllNodes(deptTreeData.value)
  }
})

/**
 * 将树形数据扁平化，只保留叶节点
 * @param {Array} treeData 树形数据
 * @param {String} parentPath 父级路径，用于构建完整的显示名称
 * @returns {Array} 扁平化的叶节点数组
 */
function flattenTreeToLeafNodes(treeData, parentPath = '') {
  const result = []
  
  if (!Array.isArray(treeData)) {
    return result
  }
  
  treeData.forEach(node => {
    // 构建当前节点的完整路径名称
    const nodeName = node.label || node.deptName || node.name || `部门${node.id}`
    const currentPath = parentPath ? `${parentPath} / ${nodeName}` : nodeName
    
    // 判断是否为叶节点（没有子节点或子节点为空）
    const hasChildren = node.children && Array.isArray(node.children) && node.children.length > 0
    
    if (!hasChildren) {
      // 叶节点，添加到结果中
      result.push({
        id: node.id,
        label: currentPath,
        value: node.id,
        deptName: nodeName,
        fullPath: currentPath,
        originalData: node
      })
    } else {
      // 非叶节点，递归处理子节点
      const childNodes = flattenTreeToLeafNodes(node.children, currentPath)
      result.push(...childNodes)
    }
  })
  
  return result
}

/**
 * 将树形数据扁平化，包含所有节点
 * @param {Array} treeData 树形数据
 * @param {String} parentPath 父级路径，用于构建完整的显示名称
 * @returns {Array} 扁平化的所有节点数组
 */
function flattenTreeToAllNodes(treeData, parentPath = '') {
  const result = []
  
  if (!Array.isArray(treeData)) {
    return result
  }
  
  treeData.forEach(node => {
    // 构建当前节点的完整路径名称
    const nodeName = node.label || node.deptName || node.name || `部门${node.id}`
    const currentPath = parentPath ? `${parentPath} / ${nodeName}` : nodeName
    
    // 添加当前节点到结果中
    result.push({
      id: node.id,
      label: currentPath,
      value: node.id,
      deptName: nodeName,
      fullPath: currentPath,
      originalData: node
    })
    
    // 如果有子节点，递归处理
    if (node.children && Array.isArray(node.children) && node.children.length > 0) {
      const childNodes = flattenTreeToAllNodes(node.children, currentPath)
      result.push(...childNodes)
    }
  })
  
  return result
}

/**
 * 获取部门选项数据
 */
async function fetchDeptOptions() {
  try {
    const response = await deptTreeSelect()
    deptTreeData.value = response.data || []
  } catch (error) {
    console.error('获取部门选项失败:', error)
    deptTreeData.value = []
  }
}

/**
 * 处理选择变化
 */
function handleChange(value) {
  selectedValue.value = value
  emit('update:modelValue', value)
  
  // 找到选中的部门完整信息
  const selectedDept = flatDeptOptions.value.find(dept => dept.id === value)
  emit('change', value, selectedDept)
}

/**
 * 处理清空
 */
function handleClear() {
  selectedValue.value = undefined
  emit('update:modelValue', undefined)
  emit('clear')
}

// 监听modelValue变化
watch(() => props.modelValue, (newValue) => {
  selectedValue.value = newValue
}, { immediate: true })

// 组件挂载时获取数据
onMounted(() => {
  fetchDeptOptions()
})
</script>